#include "imagefactory.h"

#include <libgfl.h>

#include <iostream>

namespace raytracer {

ImageFactory::ImageFactory()
   : Singleton<ImageFactory>()
   , m_data(0)
   , m_info()
{
   GFL_ERROR l_error = gflLibraryInit();
   if( l_error ) {
      //throw exp
      std::cout << gflGetErrorString(l_error) << std::endl;
   }
   else {
      std::cout << "GFL-SDK loaded" << std::endl;
      std::cout << gflGetNumberOfFormat() << " formats managed" << std::endl;
//      for(unsigned int n=0; n < gflGetNumberOfFormat(); ++n) {
//         std::cout << gflGetDefaultFormatSuffixByIndex(n) << std::endl;
//      }
   }
}

ImageFactory::~ImageFactory()
{
   gflLibraryExit();
}


bool ImageFactory::mLoadDataBuffer(
   const std::string &a_filename,
   const GFL_BITMAP_TYPE &a_gfl_type)
{
   GFL_LOAD_PARAMS l_load_param;

   gflGetDefaultLoadParams(
      &l_load_param);

   l_load_param.LinePadding = 0;
   l_load_param.ColorModel  = a_gfl_type;

  GFL_ERROR l_error =
   gflLoadBitmap(
      a_filename.data(),
      &m_data,
      &l_load_param,
      &m_info);

   if( l_error ) {
      std::cout << gflGetErrorString(l_error) << std::endl;
      return false;
   }
   return true;
}

void ImageFactory::mClearDataBuffer()
{
   if(m_data) {
      gflFreeBitmap(m_data);
      m_data = 0;
   }
}

bool ImageFactory::mSaveDataBuffer(
   const std::string &a_filename)
{
   GFL_SAVE_PARAMS l_save_params;
   gflGetDefaultSaveParams(&l_save_params);

   l_save_params.FormatIndex =
      this->mGetFormatIndex(a_filename);

   GFL_ERROR l_error =
      gflSaveBitmap(
         (char *)a_filename.data(),
         m_data,
         &l_save_params);

   if( l_error ) {
      std::cout << gflGetErrorString(l_error) << std::endl;
      return false;
   }
   return true;
}

void ImageFactory::mCreateDataBuffer(
   const size_t &a_width,
   const size_t &a_height,
   const GFL_BITMAP_TYPE &a_gfl_type)
{
   m_data = gflAllockBitmap(
      a_gfl_type,a_width,a_height,1,0);
}


GFL_INT32 ImageFactory::mGetFormatIndex(
   const std::string &a_filename)
{
   size_t l_pos(a_filename.find_last_of( '.'));
   std::string l_extension(
      (l_pos != -1)?a_filename.substr(l_pos+1):"png");
   return gflGetFormatIndexByName(l_extension.data());
}

} //end of namespace
